home *** CD-ROM | disk | FTP | other *** search
- /* scrinfo.c - access information about screen contents and attributes
- *****************************************************************************
- expecTerm version 1.0 beta
- Mark Weissman
- Christopher Matheus
- Copyright 1992 by GTE Laboratories Incorporated.
-
- Portions of this work are in the public domain. Permission to use,
- copy, modify, and distribute this software and its documentation for
- any purpose and without fee is hereby granted, provided that the above
- copyright notice appear in all copies and that both the copyright
- notice and warranty disclaimer appear in supporting documentation, and
- that the names of GTE Laboratories or any of their entities not be
- used in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- GTE disclaims all warranties with regard to this software, including
- all implied warranties of merchantability and fitness for a particular
- purpose, even if GTE Laboratories Incorporated knows about the
- purpose. In no event shall GTE be liable for any special, indirect or
- consequential damages or any damages whatsoever resulting from loss of
- use, data or profits, whether in an action of contract, negligence or
- other tortuous action, arising out of or in connection with the use or
- performance of this software.
-
- This code is based on and may include parts of Don Libes' expect code:
- expect written by: Don Libes, NIST, 2/6/90
- Design and implementation of expect was paid for by U.S. tax
- dollars. Therefore it is public domain. However, the author and NIST
- would appreciate credit if this program or parts of it are used.
- ******************************************************************************
-
- Written by: Chris Matheus May1992
- Mark Weissman
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <tcl.h>
- #include "win.h"
- #include "global.h"
- #include "scrinfo.h"
-
- void printsr(sr)
- ScreenRegion *sr;
- {
- printf(" screen region: r:%d %d c:%d %d r_r:%d %d r_c:%d %d rrp:%c rcp:%c, casep: %c\n",
- sr->rowmin,sr->rowmax,sr->colmin, sr->colmax,
- sr->relrowmin,sr->relrowmax,sr->relcolmin, sr->relcolmax,
- sr->relrowp, sr->relcolp, sr->casep);
- }
-
- char *ScreenDumpContents(minrow,maxrow,mincol,maxcol,
- scr_attr_flag, non_print_char, casep)
- int maxrow, maxcol, minrow, mincol;
- char scr_attr_flag;
- char non_print_char;
- char casep;
- {
- int col, row;
- static char dumpbuf[XMAX*YMAX], *bufp;
- extern char charyx();
- extern char attryx();
-
- /* printf("%d %d %d %d %d\n",minrow,maxrow,mincol,maxcol,scr_attr_flag); */
-
- bufp = dumpbuf;
- if (scr_attr_flag == SCR_ATTRIBUTES) { /* scr_attr_flag: -1 -> attr, 1 -> contents */
- for (row = minrow; row <= maxrow; row++) {
- for (col = mincol; col <= maxcol; col++)
- *bufp++ = (charyx(row,col)) ? attryx(row,col) : '_';
- if (row < maxrow) *bufp++ = '\n';
- }
- }
- else if (scr_attr_flag == SCR_CONTENTS) {
- for (row = minrow; row <= maxrow; row++) {
- for (col = mincol; col <= maxcol; col++) {
- *bufp = charyx(row,col);
- if (!*bufp) *bufp = ' ';
- else if (non_print_char && !isprint(*bufp)) /* check */
- *bufp = non_print_char;
- else if ((casep == SCR_IGNORE) && *bufp >= 'A' && *bufp <= 'Z')
- *bufp += ('a'-'A');
- bufp++;
- }
- if (row < maxrow) *bufp++ = '\n';
- }
- }
- *bufp = '\0';
- return(dumpbuf);
- }
-
- /* get contents or attributes for specified screen_region */
- char *get_screen_region(sr)
- ScreenRegion *sr;
- {
- int rowmin, rowmax, colmin, colmax;
- long Cols = Session->columns;
- long Rows = Session->rows;
-
- if (sr->relrowp == SCR_RELATIVE) {
- rowmin = (sr->relrowmin + Session->y);
- if (rowmin < sr->rowmin) { /* check within clip region */
- rowmin = sr->rowmin;
- } else if (rowmin > (Rows - 1)) { /* check within screen */
- rowmin = (Rows - 1);
- }
- rowmax = (sr->relrowmax + Session->y);
- if (rowmax > sr->rowmax) { /* check within clip region */
- rowmax = sr->rowmax;
- } else if (rowmax > (Rows - 1)) { /* check within screen */
- rowmax = (Rows - 1);
- }
-
- } else {
- rowmin = sr->rowmin;
- rowmax = sr->rowmax;
- }
-
- if (sr->relcolp == SCR_RELATIVE) {
- colmin = (sr->relcolmin + Session->x);
- if (colmin < sr->colmin) { /* check within clip region */
- colmin = sr->colmin;
- } else if (colmin > (Cols - 1)) { /* check within screen */
- colmin = (Cols - 1);
- }
-
- colmax = (sr->relcolmax + Session->x);
- if (colmax > sr->colmax) { /* check within clip region */
- colmax = sr->colmax;
- } else if (colmax > (Cols - 1)) { /* check within screen */
- colmax = (Cols - 1);
- }
-
- } else {
- colmin = sr->colmin;
- colmax = sr->colmax;
- }
-
-
- return ScreenDumpContents(rowmin, rowmax, colmin, colmax, sr->match_type, sr->non_print_char, sr->casep);
- }
-
-
- void
- init_screen_region(sr)
- ScreenRegion *sr;
- {
- char *v;
-
- if ((v = get_var(CLIP_ROWMIN_VAR)) > (char *)0) sr->rowmin = atoi(v);
- else sr->rowmin = 0;
- if ((v = get_var(CLIP_ROWMAX_VAR)) > (char *)0) sr->rowmax = atoi(v);
- else if (Session) sr->rowmax = (Session->rows - 1);
- if ((v = get_var(CLIP_COLMIN_VAR)) > (char *)0) sr->colmin = atoi(v);
- else sr->colmin = 0;
- if ((v = get_var(CLIP_COLMAX_VAR)) > (char *)0) sr->colmax = atoi(v);
- else if (Session) sr->colmax = (Session->columns - 1);
-
- sr->relrowmin = REL_ROWMIN_DEFAULT;
- sr->relrowmax = REL_ROWMAX_DEFAULT;
- sr->relcolmin = REL_COLMIN_DEFAULT;
- sr->relcolmax = REL_COLMAX_DEFAULT;
- sr->relrowp = SCR_ABSOLUTE;
- sr->relcolp = SCR_ABSOLUTE;
- sr->match_type = SCR_SERIAL;
- sr->non_print_char = SCR_DEFAULT_NON_PRINT_CHAR;
- sr->casep = SCR_NORMAL;
- sr->breaksp = SCR_BREAKS;
- }
-
- /*ARGSUSED*/
- int
- cmdScreenInfo(clientData, interp, argc, argv)
- ClientData clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- int m = -1; /* master process file descriptor */
- int i, screen_argp = 0;
- int previous_results = 0;
- char temp_buf[128];
- ScreenRegion sr_struct, *sr = &sr_struct;
-
- for (i=1;i<argc;i++) {
- if (streq(argv[i],"-i")) {
- if (argc == ++i) goto usage_error;
- m = atoi(argv[i]);
- break;
- }
- }
- if ((m == -1) && (update_master(&m) == 0)) return(TCL_ERROR);
-
- if (!SetSessionFromFD(m)) {
- tcl_error("spawn_id %d not associated with a terminal emulator.", m);
- return TCL_ERROR;
- }
-
- if (argc > 1) init_screen_region(sr);
-
- for (i=1;i<argc;i++) {
- if (streq(argv[i],"-i")) {
- ++i; continue;
- } else if (streq(argv[i],"-numrows")) {
- previous_results = 1;
- sprintf(temp_buf,"%d",Session->rows);
- Tcl_AppendElement(interp, temp_buf, 0);
- } else if (streq(argv[i],"-numcols") || streq(argv[i],"-numcolumns")) {
- previous_results = 1;
- sprintf(temp_buf,"%d",Session->columns);
- Tcl_AppendElement(interp, temp_buf, 0);
- } else if (streq(argv[i],"-cursor_row")) {
- previous_results = 1;
- sprintf(temp_buf,"%d",Session->y);
- Tcl_AppendElement(interp, temp_buf, 0);
- } else if (streq(argv[i],"-cursor_col") || (streq(argv[i],"-cursor_column"))) {
- previous_results = 1;
- sprintf(temp_buf,"%d",Session->x);
- Tcl_AppendElement(interp, temp_buf, 0);
- } else if (streq(argv[i],"-info")) {
- sprintf(interp->result,
- "rows=%d:%d\ncols=%d:%d\nrrows=%d:%d\nrcols=%d:%d\nrelrowp=%s\nrelcolp=%s\nmatch_type=%s\nCase=%s\n",
- sr->rowmin,sr->rowmax,sr->colmin, sr->colmax,
- sr->relrowmin,sr->relrowmax,sr->relcolmin, sr->relcolmax,
- ((sr->relrowp==SCR_RELATIVE)?"True":"False"),
- ((sr->relcolp==SCR_RELATIVE)?"True":"False"),
- ((sr->match_type==SCR_ATTRIBUTES)?"Attributes":
- (sr->match_type==SCR_CONTENTS)?"Contents":
- (sr->match_type==SCR_SERIAL)?"Serial":
- "*Unknown*"),
- ((sr->casep == SCR_IGNORE)?"Ignore":"Normal")
- );
- return TCL_OK;
- } else if (parse_screen_argument(argc, argv, &i, sr)) {
- if (i == -1) return TCL_ERROR;
- screen_argp = 1;
- } else if (streq(argv[i],"-nocase")) {
- sr->match_type = SCR_CONTENTS;
- screen_argp = 1;
- } else goto usage_error;
- }
- if (screen_argp) {
- if (previous_results) Tcl_AppendElement(interp, get_screen_region(sr), TCL_STATIC);
- else Tcl_SetResult(interp, get_screen_region(sr), TCL_STATIC);
- }
- else if (!previous_results) {
- Tcl_SetResult(interp,
- ScreenDumpContents(0,(Session->rows - 1),0, (Session->columns - 1),
- SCR_CONTENTS,0,SCR_NORMAL),
- TCL_STATIC);
- }
- return TCL_OK;
-
- usage_error:
- tcl_error("usage: %s [-i spawn_id] [-nocase] [-numrows] [-numcols] [-cursor_row] [-cursor_col] [screen region]", argv[0]);
- return TCL_ERROR;
-
- }
-
- int
- parse_screen_argument(argc, argv, i, sr)
- int argc, *i;
- char **argv;
- ScreenRegion *sr;
- {
- int min, max;
- extern double atof();
-
- if (streq(argv[*i],"-screen") || streq(argv[*i],"-scr")) {
- sr->match_type = SCR_CONTENTS;
- } else if ((streq(argv[*i],"-attr")) || (streq(argv[*i],"-attributes"))) {
- sr->match_type = SCR_ATTRIBUTES;
- } else if (streq(argv[*i],"-serial")) {
- sr->match_type = SCR_SERIAL;
- } else if (streq(argv[*i],"-nocase")) {
- sr->casep = SCR_IGNORE;
- return(0); /* return 0 so expect can reuse -nocase flag */
- } else if (streq(argv[*i],"-nobreaks")) {
- if (sr->match_type == SCR_SERIAL) sr->match_type = SCR_CONTENTS;
- sr->breaksp = SCR_NOBREAKS;
- } else if (streq(argv[*i],"-breaks")) {
- if (sr->match_type == SCR_SERIAL) sr->match_type = SCR_CONTENTS;
- sr->breaksp = SCR_BREAKS;
- } else if (streq(argv[*i],"-breaks")) {
- if (sr->match_type == SCR_SERIAL) sr->match_type = SCR_CONTENTS;
- sr->breaksp = SCR_BREAKS;
- } else if (streq(argv[*i],"-cols") || streq(argv[*i],"-columns") ||
- streq(argv[*i],"-clipcol") || streq(argv[*i],"-clipcolumn")) {
- if (parse_min_max((*i+1==argc), argv[*i+1], &min, &max,
- -(Session->columns-1), (Session->columns-1))
- == TCL_ERROR) goto number_error;
- ++(*i);
- if (sr->match_type == SCR_SERIAL) sr->match_type = SCR_CONTENTS;
- if (min < 0) min = min + Session->columns;
- if (max < 0) max = max + Session->columns;
- if (sr->colmin < min) sr->colmin = min;
- if (sr->colmax > max) sr->colmax = max;
- } else if (streq(argv[*i],"-rows") || streq(argv[*i],"-cliprow")) {
- if (parse_min_max((*i+1==argc), argv[*i+1], &min, &max, -(Session->rows - 1), (Session->rows - 1))
- == TCL_ERROR) goto number_error;
- ++(*i);
- if (sr->match_type == SCR_SERIAL) sr->match_type = SCR_CONTENTS;
- if (min < 0) min = min + Session->rows;
- if (max < 0) max = max + Session->rows;
- if (sr->rowmin < min) sr->rowmin = min;
- if (sr->rowmax > max) sr->rowmax = max;
- } else if (streq(argv[*i],"-rcols") || streq(argv[*i],"-rcolumns")) {
- if (parse_min_max((*i+1==argc), argv[*i+1], &min, &max, -(Session->columns - 1), (Session->columns - 1))
- == TCL_ERROR) goto number_error;
- ++(*i);
- if (sr->match_type == SCR_SERIAL) sr->match_type = SCR_CONTENTS;
- sr->relcolmin += min;
- sr->relcolmax += max;
- sr->relcolp = SCR_RELATIVE;
- } else if (streq(argv[*i],"-rrows")) {
- if (parse_min_max((*i+1==argc), argv[*i+1], &min, &max, -(Session->rows - 1), (Session->rows - 1))
- == TCL_ERROR) goto number_error;
- ++(*i);
- if (sr->match_type == SCR_SERIAL) sr->match_type = SCR_CONTENTS;
- sr->relrowmin += min;
- sr->relrowmax += max;
- sr->relrowp = SCR_RELATIVE;
- } else if (streq(argv[*i],"-nonprint")) {
- if ((*i+1) == argc) goto usage_error;
- ++(*i);
- sr->match_type = SCR_CONTENTS;
- sr->non_print_char = argv[*i][0];
- } else return 0; /* argv[*i] is not a screen argument */
-
- return 1; /* argv[*i] is a screen argument; return new index */
-
- usage_error:
- tcl_error("error parsing %s argument: %s", argv[0], argv[*i]);
- return (*i = -1);
-
- number_error:
- tcl_error("badly formed number or range for %s: %s", argv[*i-1], argv[*i]);
- return (*i = -1);
- }
-
- int parse_min_max(argc_error, argument, min, max, absmin, absmax)
- char *argument;
- int argc_error, *min, *max;
- {
- char argbuf[128], *arg;
- char *minptr, *maxptr;
-
- if (argc_error) return TCL_ERROR;
-
- strcpy(argbuf, argument);
- minptr = maxptr = arg = argbuf;
- for (;*arg;arg++) {
- if (*arg == ':') {
- *arg = '\0';
- maxptr = arg+1;
- } else if (!(*arg == '$' || *arg == '^' || *arg == '-' || isdigit(*arg)))
- return TCL_ERROR;
- }
-
- *min = my_atoi(minptr, absmin, absmax);
- if (*min < absmin) *min = absmin;
- *max = my_atoi(maxptr, absmin, absmax);
- if (*max > absmax) *max = absmax;
-
- return TCL_OK;
- }
-
- int my_atoi(n, absmin, absmax)
- char *n;
- int absmin, absmax;
- {
- if (*n == '$') return absmax;
- if (*n == '^') return absmin;
- return atoi(n);
- }
-
- void
- init_scr_region_variables()
- {
- Tcl_SetVar(interp,CLIP_ROWMIN_VAR,"-1",0);
- Tcl_SetVar(interp,CLIP_ROWMAX_VAR,"-1",0);
- Tcl_SetVar(interp,CLIP_COLMIN_VAR,"-1",0);
- Tcl_SetVar(interp,CLIP_COLMAX_VAR,"-1",0);
- }
-
-
- int get_start_row(sr, start)
- ScreenRegion *sr;
- int start;
- {
- int row, cols, result=0;
- if (sr->relrowp == 'r') row = Session->y + sr->relrowmin;
- else row = sr->rowmin;
- if (sr->relcolp == 'r') cols = sr->relcolmax - sr->relcolmin;
- else cols = sr->colmax - sr->colmin + 2;
- if (cols) result = (row + (start / cols));
- return(result);
- }
-
- int get_start_col(sr, start)
- ScreenRegion *sr;
- int start;
- { int col, cols;
- if (sr->relcolp == 'r') col = Session->x + sr->relcolmin;
- else col = sr->colmin;
- if (sr->relcolp == 'r') cols = sr->relcolmax - sr->relcolmin;
- else cols = sr->colmax - sr->colmin + 2;
- if (cols) return (col + (start % cols));
- else return 0;
- }
-